package com.qut.graduate.busrtquery.fragment;

import android.content.Context;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.baidu.location.BDLocation;
import com.baidu.mapapi.map.BaiduMap;
import com.baidu.mapapi.map.MapPoi;
import com.baidu.mapapi.map.MapStatus;
import com.baidu.mapapi.map.MapStatusUpdate;
import com.baidu.mapapi.map.MapStatusUpdateFactory;
import com.baidu.mapapi.map.MapView;
import com.baidu.mapapi.map.Marker;
import com.baidu.mapapi.map.MyLocationConfiguration;
import com.baidu.mapapi.map.MyLocationData;
import com.baidu.mapapi.model.LatLng;
import com.baidu.mapapi.search.geocode.GeoCoder;
import com.baidu.mapapi.search.geocode.ReverseGeoCodeOption;
import com.baidu.mapapi.search.geocode.ReverseGeoCodeResult;
import com.baidu.mapapi.utils.DistanceUtil;
import com.bumptech.glide.Glide;
import com.makeramen.roundedimageview.RoundedImageView;
import com.qut.graduate.busrtquery.BRTQConstant;
import com.qut.graduate.busrtquery.R;
import com.qut.graduate.busrtquery.bean.User;
import com.qut.graduate.busrtquery.listener.MyOrientationListener;
import com.qut.graduate.busrtquery.ui.MainActivity;
import com.qut.graduate.busrtquery.utils.baidumap.BaiduMapUtils;
import com.qut.graduate.busrtquery.utils.common.LogUtils;
import com.qut.graduate.busrtquery.utils.net.NetworkUtils;
import com.qut.graduate.busrtquery.utils.store.SPUtils;
import com.qut.graduate.busrtquery.utils.uiabout.ScreenUtils;

import java.io.File;

import cn.bmob.v3.BmobUser;

/**
 * 定位导航界面
 *
 * @Author WLL
 * @Time: 2019/3/23 16:38
 */
public class LocNavFragment extends BaseFragment {
    private static final String TAG = "LocationNavigationFragm";
    private Context mContext;
    private boolean isFirstIn = true; // 是否是第一次定位，若是则将地图切换到定位位置
    private boolean isFirstClick = true; // 是否是第一次点击地图空间
    private MyOrientationListener myOrientationListener;
    private MyLocationConfiguration.LocationMode locationMode; // 定位图层显示方式,地图SDK支持三种定位模式：NORMAL（普通态）, FOLLOWING（跟随态）, COMPASS（罗盘态）
    private BDLocation bdLocation; // 当前定位的所有信息
    private LatLng mCurrentLatLng; // 当前经纬度
    private LatLng mAimLatLng; // 目的地经纬度
    private float mCurrentX; // 当前方向
    private float mCurrentAccracy; // 当前定位精度
    private double mLatitude; // 当前纬度
    private double mLongitude; // 当前经度
    private ReverseGeoCodeResult geocodedResult; // 地图上的点编译得到的信息
    GeoCoder mSearch = null;
    private Marker marker; // 覆盖物相关
    private BaiduMap mBaiduMap;
    private MapView mMapView = null;
    private DrawerLayout drawer;
    private RoundedImageView mUserHeaderImg;
    private LinearLayout mTopLayout;
    private TextView mSearchText;
    private ImageButton mTrafficImgBtn;
    private ImageButton mCoverageImgBtn;
    private LinearLayout mCoverageLayout;
    private ImageButton m2dMapImgBtn;
    private ImageButton mSiteMapImgBtn;
    private ImageButton m3dMapImgBtn;
    private ImageButton mLocationImgBtn;
    private ImageButton mZoomIn;
    private ImageButton mZoomOut;
    private LinearLayout mNavigateLayout;
    private LinearLayout mAddressInfoLayout;
    private TextView mInfoName;
    private TextView mInfoDistance;
    private TextView mInfoAddress;
    private String placeAddress;
    private String placeName;

    @Override
    protected int getLayoutId() {
        return R.layout.fragment_loc_nav;
    }

    protected void init() {
        mContext = this.getActivity();
        initView();
        initBaiduMap();
        initLocation();
    }

    @Override
    public void onHiddenChanged(boolean hidden) {
        super.onHiddenChanged(hidden);
        if (!hidden) {
            User user = BmobUser.getCurrentUser(User.class);
            if (user != null) {
                SPUtils preferenceUtils = SPUtils.getInstance(getActivity());
                String headerPath = preferenceUtils.getString(getString(R.string.preference_user_header_path), "");
                File headerFile = new File(headerPath);
                if (!(NetworkUtils.getNetworkType(getActivity()) == BRTQConstant.NETWORK_NONE)) {
                    if (!headerPath.equals("") && headerFile.exists())
                        Glide.with(this).load(headerPath).into(mUserHeaderImg);
                    if (user.getHeadImg() != null && user.getHeadImg().getFileUrl() != null)
                        Glide.with(this).load(user.getHeadImg().getFileUrl()).placeholder(R.mipmap.detach_male).into(mUserHeaderImg);
                    else Glide.with(this).load(R.mipmap.detach_male).into(mUserHeaderImg);
                } else { // 没有网络从本地加载
                    if (!headerPath.equals("") && headerFile.exists())
                        Glide.with(this).load(headerPath).into(mUserHeaderImg);
                    else Glide.with(this).load(R.mipmap.detach_male).into(mUserHeaderImg);
                }
            } else {
                Glide.with(this).load(R.mipmap.detach_male).into(mUserHeaderImg);
            }
        }
    }

    /**
     * 添加地图的触摸、点击、长按事件等
     */
    private void initBaiduMap() {
        mSearch = GeoCoder.newInstance();
        mSearch.setOnGetGeoCodeResultListener((MainActivity) getActivity());

        // 监听地图触摸事件,若当前是跟随或者3d模式触摸返回正常模式
        mBaiduMap.setOnMapTouchListener(new BaiduMap.OnMapTouchListener() {
            @Override
            public void onTouch(MotionEvent motionEvent) {
                locationMode = MyLocationConfiguration.LocationMode.NORMAL;
                mBaiduMap.setMyLocationConfiguration(new MyLocationConfiguration(locationMode, true, null));
                mLocationImgBtn.setImageResource(R.mipmap.icon_location);
            }
        });
        // 监听地图长按事件，编译长按地点获取该点详细信息
        mBaiduMap.setOnMapLongClickListener(new BaiduMap.OnMapLongClickListener() {
            @Override
            public void onMapLongClick(LatLng latLng) {
                mNavigateLayout.setVisibility(View.VISIBLE);
                mAddressInfoLayout.setVisibility(View.VISIBLE);
                // 编译长按的地点获取该地点的信息，并添加标记物
                mAimLatLng = latLng;
                marker = BaiduMapUtils.addOverlay(mBaiduMap, latLng);
                mSearch.reverseGeoCode(new ReverseGeoCodeOption().location(latLng));
                // 计算长按地图所在点到当前定位的距离
                double distance = DistanceUtil.getDistance(mCurrentLatLng, latLng);
                String disStr = "";
                if (distance < 1000) disStr = String.valueOf((int) distance) + " m";
                else disStr = String.format("%.2f", (distance / 1000)) + " km";
                mInfoDistance.setText(disStr);
                // 判断当前是否是第一次点击，若不是第一次点击则将第一次点击后隐藏的控件显示出来
                if (isFirstClick) {
                    mBaiduMap.setViewPadding(ScreenUtils.dp2px(10), 0, 0, ScreenUtils.dp2px(100));
                } else {
                    mTopLayout.setVisibility(View.VISIBLE);
                    mCoverageImgBtn.setVisibility(View.VISIBLE);
                    mTrafficImgBtn.setVisibility(View.VISIBLE);
                    mBaiduMap.setViewPadding(ScreenUtils.dp2px(10), 0, 0, ScreenUtils.dp2px(100));
                }
                isFirstClick = true;
            }
        });
        // 监听地图点击事件，首先判断切换地图模式的layout是否显示，若该layout显示，第一次点击应隐藏该layout
        // 若该layout不显示，地图有覆盖物表示已经编译地点，第一次点击应该清除覆盖物、隐藏导航等布局
        // 若地图上没有覆盖物，即当前什么都没做，第一次点击隐藏除定位、比例尺之外的ImageButton
        // 若不是第一次点击则将隐藏的控件显示出来
        mBaiduMap.setOnMapClickListener(new BaiduMap.OnMapClickListener() {
            @Override
            public void onMapClick(LatLng latLng) {
                if (mCoverageLayout.getVisibility() == View.VISIBLE) {
                    mCoverageLayout.setVisibility(View.GONE);
                } else {
                    mBaiduMap.clear();
                    mBaiduMap.setViewPadding(ScreenUtils.dp2px(10), 0, 0, 0);
                    if (isFirstClick) {
                        if (marker != null) {
                            marker = null;
                            isFirstClick = true;
                            mNavigateLayout.setVisibility(View.GONE);
                            mAddressInfoLayout.setVisibility(View.GONE);
                        } else {
                            isFirstClick = false;
                            mTopLayout.setVisibility(View.GONE);
                            mCoverageImgBtn.setVisibility(View.GONE);
                            mTrafficImgBtn.setVisibility(View.GONE);
                        }
                    } else {
                        isFirstClick = true;
                        mTopLayout.setVisibility(View.VISIBLE);
                        mCoverageImgBtn.setVisibility(View.VISIBLE);
                        mTrafficImgBtn.setVisibility(View.VISIBLE);
                    }
                }
            }

            @Override
            public boolean onMapPoiClick(MapPoi mapPoi) {
                return false;
            }
        });
    }

    /**
     * 显示编译后的地址信息
     *
     * @param reverseGeoCodeResult
     */
    public void setNavAddressInfo(ReverseGeoCodeResult reverseGeoCodeResult) {
        geocodedResult = reverseGeoCodeResult;
        placeAddress = reverseGeoCodeResult.getSematicDescription();
        if (reverseGeoCodeResult.getPoiList() != null)
            if (reverseGeoCodeResult.getPoiList().get(0).getName() != null)
                placeName = reverseGeoCodeResult.getPoiList().get(0).getName();
        if (placeName == null) mInfoName.setText("无法获取地点名称");
        else mInfoName.setText(placeName);
        if (placeAddress == null) mInfoAddress.setText("网络问题,无法获取详细地址");
        else mInfoAddress.setText(placeAddress);
    }

    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.loc_nav_user_roundImage:
                drawer.openDrawer(GravityCompat.START);
                break;
            case R.id.loc_nav_traffic_img_btn: // 交通情况
                BaiduMapUtils.getTrafficCondition(mBaiduMap, mTrafficImgBtn);
                break;
            case R.id.location_img_btn:
                changeLocationType();
                break;
            case R.id.loc_nav_coverage_img_btn:
                if (mCoverageLayout.getVisibility() == View.GONE)
                    mCoverageLayout.setVisibility(View.VISIBLE);
                else mCoverageLayout.setVisibility(View.GONE);
                break;
            case R.id.loc_nav_navigation_layout:
                // 调用主页的公交路径规划方法
                LogUtils.d("----从导航界面跳转到换乘界面----mCurrentLatLng: " + mCurrentLatLng + "----mAimLatLng: " + mAimLatLng, getClass());
                ((MainActivity) getActivity()).gotoTransfer("我的位置", placeName, mCurrentLatLng, mAimLatLng);
                break;
            case R.id.loc_nav_search_text:
                ((MainActivity) getActivity()).gotoTransfer("我的位置", "", mCurrentLatLng, mCurrentLatLng);
                break;
            case R.id.loc_nav_map_2d_img_btn:
                BaiduMapUtils.changeMapType(mBaiduMap, BaiduMap.MAP_TYPE_NORMAL, 45, 15.0f, mCoverageLayout);
                break;
            case R.id.loc_nav_map_site_img_btn:
                BaiduMapUtils.changeMapType(mBaiduMap, BaiduMap.MAP_TYPE_SATELLITE, 45, 15.0f, mCoverageLayout);
                break;
            case R.id.loc_nav_map_3d_img_btn:
                BaiduMapUtils.changeMapType(mBaiduMap, BaiduMap.MAP_TYPE_NORMAL, -90, 19.0f, mCoverageLayout);
                locationMode = MyLocationConfiguration.LocationMode.FOLLOWING;
                //mCoverageLayout.setVisibility(View.GONE);
                changeLocationType();
                break;
            case R.id.zoom_in:
                BaiduMapUtils.zoomIn(mBaiduMap, mZoomOut, mZoomIn);
                break;
            case R.id.zoom_out:
                BaiduMapUtils.zoomOut(mBaiduMap, mZoomOut, mZoomIn);
                break;
        }
    }

    private void changeLocationType() {
        if (locationMode == MyLocationConfiguration.LocationMode.NORMAL) {
            locationMode = MyLocationConfiguration.LocationMode.FOLLOWING;
            mLocationImgBtn.setImageResource(R.mipmap.icon_follow);
        } else if (locationMode == MyLocationConfiguration.LocationMode.FOLLOWING) {
            locationMode = MyLocationConfiguration.LocationMode.COMPASS;
            mLocationImgBtn.setImageResource(R.mipmap.icon_compass);
        } else {
            locationMode = MyLocationConfiguration.LocationMode.NORMAL;
            mLocationImgBtn.setImageResource(R.mipmap.icon_location);
        }
        MapStatus.Builder builder = new MapStatus.Builder();
        if (locationMode == MyLocationConfiguration.LocationMode.FOLLOWING)
            builder.rotate(mCurrentX).overlook(0).zoom(18f);
        else
            builder.rotate(0).overlook(0).zoom(18f);
        mBaiduMap.setMyLocationConfiguration(new MyLocationConfiguration(locationMode, true, null));
        mBaiduMap.animateMapStatus(MapStatusUpdateFactory.newMapStatus(builder.build()));
    }

    private void initView() {
        mMapView = mRootView.findViewById(R.id.bmapView); // 获取地图控件引用
        mBaiduMap = mMapView.getMap();
        mBaiduMap.setViewPadding(ScreenUtils.dp2px(10), 0, 0, 0);
        BaiduMapUtils.changeDefaultBaiDuMapView(mMapView, mBaiduMap); // 比列尺、放大、缩小按钮、图标等的显示与否
        MapStatusUpdate msu = MapStatusUpdateFactory.zoomTo(15.0f); // 根据给定增量缩放地图级别
        mBaiduMap.setMapStatus(msu);

        if (getActivity() != null) drawer = getActivity().findViewById(R.id.main_drawer_layout);
        mTopLayout = mRootView.findViewById(R.id.loc_nav_top_layout);
        mUserHeaderImg = mRootView.findViewById(R.id.loc_nav_user_roundImage);
        mSearchText = mRootView.findViewById(R.id.loc_nav_search_text);
        mTrafficImgBtn = mRootView.findViewById(R.id.loc_nav_traffic_img_btn);
        mCoverageImgBtn = mRootView.findViewById(R.id.loc_nav_coverage_img_btn);
        mCoverageLayout = mRootView.findViewById(R.id.loc_nav_coverage_layout);
        m2dMapImgBtn = mRootView.findViewById(R.id.loc_nav_map_2d_img_btn);
        mSiteMapImgBtn = mRootView.findViewById(R.id.loc_nav_map_site_img_btn);
        m3dMapImgBtn = mRootView.findViewById(R.id.loc_nav_map_3d_img_btn);
        mLocationImgBtn = mRootView.findViewById(R.id.location_img_btn);
        mZoomIn = mRootView.findViewById(R.id.zoom_in);
        mZoomOut = mRootView.findViewById(R.id.zoom_out);
        mNavigateLayout = mRootView.findViewById(R.id.loc_nav_navigation_layout);
        mAddressInfoLayout = mRootView.findViewById(R.id.loc_nav_address_info_layout);
        mInfoName = mRootView.findViewById(R.id.loc_nav_info_name);
        mInfoDistance = mRootView.findViewById(R.id.loc_nav_info_distance);
        mInfoAddress = mRootView.findViewById(R.id.loc_nav_info_address);

        mCoverageLayout.setVisibility(View.GONE);
        mAddressInfoLayout.setVisibility(View.GONE);
        mNavigateLayout.setVisibility(View.GONE);

        mUserHeaderImg.setOnClickListener(this);
        mSearchText.setOnClickListener(this);
        mTrafficImgBtn.setOnClickListener(this);
        m2dMapImgBtn.setOnClickListener(this);
        m3dMapImgBtn.setOnClickListener(this);
        mSiteMapImgBtn.setOnClickListener(this);
        mCoverageImgBtn.setOnClickListener(this);
        mLocationImgBtn.setOnClickListener(this);
        mZoomIn.setOnClickListener(this);
        mZoomOut.setOnClickListener(this);
        mNavigateLayout.setOnClickListener(this);
    }

    private void initLocation() {
        mBaiduMap.setMapType(BaiduMap.MAP_TYPE_NORMAL);
        mBaiduMap.setMyLocationEnabled(true); // 开启定位图层
        myOrientationListener = new MyOrientationListener(getActivity());
        myOrientationListener.setOnOrientationListener(new MyOrientationListener.OnOrientationListener() {
            @Override
            public void onOrientationChanged(float x) {
                mCurrentX = x;
                MyLocationData data = new MyLocationData.Builder() // 构造定位数据
                        .direction(mCurrentX) // 设定图标方向,此处设置开发者获取到的方向信息，顺时针0-360
                        .accuracy(mCurrentAccracy) // getRadius 获取定位精度,默认值0.0f
                        .latitude(mLatitude) // 百度纬度坐标
                        .longitude(mLongitude) // 百度经度坐标
                        .build();
                // 设置定位数据, 只有先允许定位图层后设置数据才会生效，参见 setMyLocationEnabled(boolean)
                mBaiduMap.setMyLocationData(data);
            }
        });
    }

    public void setBdLocation(final BDLocation bdLocation) {
        this.bdLocation = bdLocation;
        if (bdLocation != null) {
            mLatitude = bdLocation.getLatitude();
            mLongitude = bdLocation.getLongitude();
            mCurrentLatLng = new LatLng(mLatitude, mLongitude);
            mCurrentAccracy = bdLocation.getRadius();
            // 配置定位图层显示方式,三个参数的构造器,设置定位图层的配置（定位图层显示模式，是否允许方向信息，用户自定义定位图标）
            MyLocationConfiguration configuration = new MyLocationConfiguration(locationMode, true, null);
            // 设置定位图层配置信息，只有先允许定位图层后设置定位图层配置信息才会生效，参见 setMyLocationEnabled(boolean)
            mBaiduMap.setMyLocationConfiguration(configuration);
            // 判断是否为第一次定位,是的话需要定位到用户当前位置
            if (isFirstIn) {
                // 地理坐标基本数据结构
                LatLng latLng = new LatLng(bdLocation.getLatitude(), bdLocation.getLongitude());
                // 描述地图状态将要发生的变化,通过当前经纬度来使地图显示到该位置
                MapStatusUpdate msu = MapStatusUpdateFactory.newLatLng(latLng);
                // 改变地图状态
                mBaiduMap.setMapStatus(msu);
                isFirstIn = false;
                LogUtils.d("----定位信息" + LocNavFragment.this.bdLocation.getAddrStr(), this.getClass());
            }
            getActivity().runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    if (bdLocation.getAddrStr() != null && !bdLocation.getAddrStr().equals("")) {
                        String address = bdLocation.getCity() + " " + bdLocation.getLocationDescribe();
                        mSearchText.setText(address);
                    } else {
                        mSearchText.setText("网络错误,未定位到您的位置");
                    }
                }
            });
        }
    }

    @Override
    public void onStart() {
        super.onStart();
        mBaiduMap.setMyLocationEnabled(true);
        myOrientationListener.start();
    }

    @Override
    public void onStop() {
        super.onStop();
        mBaiduMap.setMyLocationEnabled(false);
        if (myOrientationListener != null) {
            myOrientationListener.stop();
        }
    }

    @Override
    public void onResume() {
        super.onResume();
        mMapView.onResume();
    }

    @Override
    public void onPause() {
        super.onPause();
        mMapView.onPause();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        mMapView.onDestroy();
        if (mSearch != null)
            mSearch.destroy();
    }

}
